<template>
  <div class="play-container">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>视频播放</span>
        </div>
      </template>
      <div class="video-container">
        <video
          id="videoElement"
          ref="videoRef"
          controls
          autoplay
          muted
          playsinline
          width="100%"
          height="600"
        >
        </video>
        <p id="status">正在初始化播放器...</p>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref, getCurrentInstance } from 'vue';
import { useRoute } from 'vue-router';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const videoRef = ref<HTMLVideoElement | null>(null);
let flvPlayer: any = null;

const initPlayer = () => {
  if (!(window as any).flvjs.isSupported()) {
    const statusElement = document.getElementById('status');
    if (statusElement) {
      statusElement.textContent = '您的浏览器不支持flv.js，无法播放此视频流';
    }
    return;
  }

  const videoElement = document.getElementById('videoElement') as HTMLVideoElement;
  const statusElement = document.getElementById('status');

  if (!videoElement || !statusElement) return;

  // 设置初始状态
  statusElement.textContent = '';

  // 处理 URL 编码
  let streamUrl = route.query.rtmpUrl as string;

  // 解码URL
  try {
    // 处理多重编码的情况
    while (streamUrl.includes('%')) {
      try {
        streamUrl = decodeURIComponent(streamUrl);
      } catch (e) {
        // 如果解码失败，说明已经解码完成
        break;
      }
    }
  } catch (e) {
    console.error('URL解码失败:', e);
  }

  // 如果存在旧的播放器，先销毁
  if (flvPlayer) {
    flvPlayer.pause();
    flvPlayer.unload();
    flvPlayer.detachMediaElement();
    flvPlayer.destroy();
    flvPlayer = null;
  }

  // 创建播放器
  flvPlayer = (window as any).flvjs.createPlayer({
    type: 'flv',
    url: streamUrl,
    isLive: true,
    cors: true,
    withCredentials: false,
    hasAudio: true,
    hasVideo: true,
    enableStashBuffer: true,
    stashInitialSize: 128,
    enableWorker: true,
    lazyLoad: false,
    seekType: 'range',
    autoCleanupSourceBuffer: true,
    autoCleanupMaxBackwardDuration: 30,
    autoCleanupMinBackwardDuration: 10,
    headers: {
      'Accept': '*/*',
      'Accept-Encoding': 'gzip, deflate, br',
      'Connection': 'keep-alive',
      'Origin': window.location.origin,
      'Referer': window.location.href
    }
  });

  // 绑定播放器到视频元素
  flvPlayer.attachMediaElement(videoElement);
  flvPlayer.load();

  // 设置事件监听
  flvPlayer.on((window as any).flvjs.Events.ERROR, (err: any) => {
    statusElement.textContent = '播放错误: ' + err.detail;
    console.error('播放错误:', err);
  });

  flvPlayer.on((window as any).flvjs.Events.STATISTICS_INFO, () => {
    if (!videoElement.paused) {
      statusElement.textContent = '正在播放...';
    }
  });

  // 监听视频加载完成事件
  videoElement.addEventListener('loadedmetadata', () => {
    statusElement.textContent = '';
    // 确保视频是静音的
    videoElement.muted = true;
  });

  // 如果视频已经加载完成
  if (videoElement.readyState >= 1) {
    statusElement.textContent = '';
    videoElement.muted = true;
  }

  // 监听视频暂停事件
  videoElement.addEventListener('pause', () => {
    if (!videoElement.paused) return;
    statusElement.textContent = '已暂停';
  });

  // 监听视频播放事件
  videoElement.addEventListener('play', () => {
    statusElement.textContent = '正在播放...';
  });

  // 监听视频错误事件
  videoElement.addEventListener('error', (e) => {
    console.error('视频错误:', e);
    statusElement.textContent = '视频播放出错，正在重试...';
    // 尝试重新加载
    setTimeout(() => {
      flvPlayer.unload();
      flvPlayer.load();
    }, 2000);
  });
};

onMounted(() => {
  // 动态加载 flv.js
  const script = document.createElement('script');
  script.src = 'https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js';
  script.onload = () => {
    initPlayer();
  };
  document.head.appendChild(script);
});

onBeforeUnmount(() => {
  if (flvPlayer) {
    flvPlayer.pause();
    flvPlayer.unload();
    flvPlayer.detachMediaElement();
    flvPlayer.destroy();
    flvPlayer = null;
  }
});
</script>

<style scoped>
.play-container {
  padding: 20px;
}

.video-container {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#videoElement {
  width: 100%;
  height: 600px;
  background-color: #000;
}

#status {
  margin-top: 10px;
  text-align: center;
}
</style>
